<template>
  <div class="base-table">
    <div class="search-header">
      <div class="search-form">
        <!-- <SearchBar ref="searchBarRef" :fields-config="props.searchConfig.fields" v-model="searchForm"
          @update:modelValue="handleSearchChange">
          <template #buttons>
            <div class="search-bar-buttons">
              <a-button @click="handleSearch">搜索</a-button>
              <a-button type="primary" @click="handleReset">重置</a-button>
              <a-button type="primary" @click="handleExport">导出</a-button> 
            </div>
          </template>
        </SearchBar> -->
        <ToolsBar ref="toolsBarRef" :fields-config="props.searchConfig.fields" 
          v-model:toolsBarSearchForm="toolsBarSearchForm"
        />
      </div>
    </div>
    <div class="table-content">
      <vxe-table ref="tableRef" border show-overflow :column-config="{ resizable: true }"
        :virtual-y-config="{ enabled: true, gt: 20, oSize: 6 }" :sort-config="sortConfig" :export-config="exportConfig" :data="tableData"
        @sort-change="sortChangeEvent" :loading="loading" :height="props.tableConfig.height">
        <vxe-column v-if="props.tableConfig.showSelection" type="checkbox" width="60" align="center"></vxe-column>
        <vxe-column type="seq" width="70" align="center"></vxe-column>
        <vxe-column v-for="col in props.tableConfig.columnsConfig.data" :key="col.field" :field="col.field"
          :title="col.title" :sortable="col.sortable" align="center">
          <template #default="{ row }">
            <span :style="{ color: col.colorRules ? getCellColor(row[col.field], col.colorRules) : undefined }">
              {{ col.customRender ? evalExpression(col.customRender, row) : row[col.field] }}
            </span>
          </template>
        </vxe-column>
      </vxe-table>
    </div>
    <div class="pagination-container" v-if="props.paginationConfig.active">
      <a-pagination :total="paginationConfigData.total" v-model:current="paginationConfigData.currentPage"
        v-model:page-size="paginationConfigData.pageSize" :page-size-options="pageSizeOptions" show-total
        show-page-size @change="handlePageChange" @page-size-change="handlePageSizeChange" />
    </div>
  </div>
</template>

<script setup lang="ts">
import type { VxeTableInstance, VxeTablePropTypes } from 'vxe-table'
import { ref, defineProps, reactive, type PropType, onMounted, onUnmounted, provide } from 'vue'
import { getColorHex } from '../../config/GlobalColorConfig'
import SearchBar from '../utils/SearchBar.vue'
import type { TableConfig, SearchConfig, ExportConfig, ColorRule, PaginationConfig } from '@/models/BaseModels';
import { ComponentService } from '../../service/ComponentService';
import { useSSE } from '../../service/SSEService'
import ToolsBar from '../utils/ToolsBar.vue';
import type { SearchCondition } from '@/models/SearchModels';
const componentService = ComponentService.instance;

const props = defineProps({
  // 表格配置
  tableConfig: {
    type: Object as PropType<TableConfig>,
    default: () => ({
      data: [],
      columns: [],
      showSelection: false,
      height: 'auto',
    })
  },
  // 分页配置
  paginationConfig: {
    type: Object as PropType<PaginationConfig>,
    default: () => ({
      active: true,
      total: 0,
      pageSize: 10,
      currentPage: 1,
      pageSizeOptions: [10, 20, 30, 40, 50]
    })
  },
  // 搜索配置
  searchConfig: {
    type: Object as PropType<SearchConfig>,
    default: () => ({
      fields: [],
      api: {
        url: '',
        method: ''
      }
    })
  },
  // 导出配置
  exportConfig: {
    type: Object as PropType<ExportConfig>,
    default: () => ({
      mode: 'advanced',
      columnWidth: 16,
      rowHeight: 30,
      border: true,
      setHeaderBackground: true,
      headerBackgroundColor: '#c5d9f1',
    })
  }
})

const tableRef = ref<VxeTableInstance<any>>();

const tableData = ref([]);
const loading = ref(false);
const paginationConfigData = ref(props.paginationConfig);
// 分页选项: schema配置的pageSizeOptions + 配置默认的pageSize
const pageSizeOptions = ref(
  [...new Set([...props.paginationConfig.pageSizeOptions, props.paginationConfig.pageSize])].sort((a, b) => a - b)
);

let eventSource: EventSource | null = null;

onMounted(async () => {
  await handleSearch();
})
/**
 * *********************************************************************
 *                                排序配置
 * 1. 多字段排序
 * *********************************************************************
 */
const sortConfig = ref({
  multiple: true,
  chronological: true
})

const sortChangeEvent = ({ sortList }: any) => {
  console.info(sortList.map((item: any) => `${item.field},${item.order}`).join('; '))
}

/**
 * *********************************************************************
 *                                导出配置
 * 1. 普通导出xlsx、高级导出xlsx/csv/pdf TODO/html
 * 2. 导出配置边框/字体/表头背景/列宽/行高等
 * *********************************************************************
 */
const exportConfig = reactive<VxeTablePropTypes.ExportConfig>({
  type: 'xlsx',
  columnFilterMethod({ column }) {
    // 导出数据过滤掉 `type === 'seq'` 和 `type === 'checkbox'` 的列
    return !column.type || (column.type !== 'seq' && column.type !== 'checkbox');
  },
  // 导出列配置 默认不勾选多选框列和序号列
  columns: props.tableConfig.columnsConfig.data.map(col => ({
    field: col.field,
    title: col.exportField || col.title,
    columnKey: col.field
  })),
  async sheetMethod(params) {
    const { worksheet } = params

    // 获取 props.columns 的映射关系
    const columnMap = new Map(
      props.tableConfig.columnsConfig.data.map((col: any) => [col.field, col.exportField || col.title])
    )
    // 设置列宽
    worksheet.columns.forEach(sheetColumn => {
      sheetColumn.width = props.exportConfig.columnWidth
    })

    // 自定义列名  没有设置exportField的列名时使用title
    const headerRow = worksheet.getRow(1);
    headerRow.eachCell((cell, colNumber) => {
      const fieldKey = props.tableConfig.columnsConfig.data[colNumber - 1]?.field; // 获取 field
      if (fieldKey && columnMap.has(fieldKey)) {
        cell.value = columnMap.get(fieldKey); // 替换表头
      }
    });

    worksheet.eachRow((excelRow, rowIndex) => {
      // 设置表头背景
      if (rowIndex === 1 && props.exportConfig.setHeaderBackground) {
        excelRow.eachCell(excelCell => {
          excelCell.fill = {
            type: 'pattern',
            pattern: 'solid',
            fgColor: {
              argb: props.exportConfig.headerBackgroundColor
            }
          }
        })
      }
      // 设置行高
      excelRow.height = props.exportConfig.rowHeight;
      // 设置单元格边框
      excelRow.eachCell(excelCell => {
        excelCell.border = {
          top: {
            style: 'thin',
            color: {
              argb: '0f0f0f'
            }
          },
          left: {
            style: 'thin',
            color: {
              argb: '0f0f0f'
            }
          },
          bottom: {
            style: 'thin',
            color: {
              argb: '0f0f0f'
            }
          },
          right: {
            style: 'thin',
            color: {
              argb: '0f0f0f'
            }
          }
        }
      })

    })
  }
})

const handleExport = () => {
  switch (props.exportConfig.mode) {
    // 高级导出
    case 'advanced':
      tableRef.value?.openExport();
      break;
    // 普通导出
    case 'normal':
      tableRef.value?.exportData();
      break;
    default:
      // 默认普通导出
      tableRef.value?.exportData();
      break;
  }
}

/**
 * *********************************************************************
 *                                导入配置
 * *********************************************************************
 */
// const handleImport = () => {
//   tableRef.value?.importData();
// }

/**
 * *********************************************************************
 *                               列值颜色配置
 * *********************************************************************
 */
const getCellColor = (value: number, rules?: ColorRule[]): string | undefined => {
  if (!rules) return undefined;

  for (const rule of rules) {
    const { min, max, includeMin = true, includeMax = true, color } = rule;

    const minCheck = min === undefined ||
      (includeMin ? value >= min : value > min);
    const maxCheck = max === undefined ||
      (includeMax ? value <= max : value < max);

    if (minCheck && maxCheck) {
      return getColorHex(color);
    }
  }
  return undefined;
}

/**
 * *********************************************************************
 *                              自定义表达式渲染列
 * *********************************************************************
 */
const evalExpression = (expression: string, row: any) => {
  try {
    return new Function("row", `return ${expression}`)(row);
  } catch (e) {
    console.error("自定义表达式解析出错:", expression, e);
    return "";
  }
};

/**
 * *********************************************************************
 *                           搜索栏配置 SearchBar
 * *********************************************************************
 */
const searchBarRef = ref();

// 数组类型的属性要toString()
const searchForm = ref(
  Object.fromEntries(props.searchConfig.fields.map(field => [field.field, ['multiSelect', 'numberRange', 'dateTimeRange'].includes(field.type) ? [] : null]))
);
const handleSearchChange = (newValue: any) => {
  searchForm.value = newValue
}
const handleReset = () => {
  searchBarRef.value?.resetFields();
}

/**
 * *********************************************************************
  *                        工具栏搜索功能 ToolsBar
 * *********************************************************************
 */
const toolsBarRef = ref();
const toolsBarSearchForm = ref<SearchCondition[]>([
  {
    id: new Date().getTime().toString(),
    field: '',
    operator: null,
    value: null,
  }
]);


/**
 * *********************************************************************
 *                               搜索功能
 * *********************************************************************
 */

// TODO 表格搜索数据功能要放在这里       TODO 请求拦截等处理
const handleSearch = async () => {
  try {
    loading.value = true;
    tableData.value = []; // 清空数据
    stopSSE();
    startSSE({
      page: paginationConfigData.value.currentPage,
      size: paginationConfigData.value.pageSize
    });

  } catch (error) {
    console.error("搜索失败:", error);
  } finally {
    loading.value = false;
  }
}

// 钩子函数用于接收和实时追加SSE数据
const handleDataUpdate = (newData, totalRecords) => {
  tableData.value = [...tableData.value, ...newData]; // 追加新数据
  paginationConfigData.value.total = totalRecords;
};

// useSSE调用
const { startSSE, stopSSE } = useSSE(
  "http://localhost:8086/develop/sse-list",
  handleDataUpdate
);

const handlePageChange = async (page: number) => {
  paginationConfigData.value.currentPage = page;
  await handleSearch();
}

const handlePageSizeChange = async (pageSize: number) => {
  paginationConfigData.value.pageSize = pageSize;
  await handleSearch();
}

provide('handleSearch', handleSearch);

onUnmounted(() => {
  if (eventSource) {
    eventSource.close();
    eventSource = null;
  }
});
</script>

<style scoped>
.base-table {
  display: flex;
  flex-direction: column;
  flex: 1;
  height: 100%;
  width: 100%;
  padding: 16px;
  box-sizing: border-box;
  background: white;
  border-radius: 4px;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.1);
}

.table-content {
  flex: 1;
  overflow: auto;
  padding-right: 1px; /* 预留滚动条宽度，避免闪烁 */
  position: relative;
}

.pagination-container {
  display: flex;
  justify-content: flex-end;
  margin-top: 10px;
  flex-shrink: 0;
}

.search-header {
  flex-shrink: 0;
}

.search-form {
  padding-bottom: 10px;
}

.search-bar-buttons {
  display: flex;
  gap: 10px;
}
</style>